import uuid
from   google.appengine.ext import db

#========================================================================================
# ironcap.data.tags.Tag
#========================================================================================
class Tag(db.Model):
	""" A flat tag taxonomy class """
	tag_name = db.StringProperty(indexed=True) 
	
	@classmethod
	def create(cls, **kwds):
		ret = cls( key_name = str(uuid.uuid4()) )
		
		# apply keywords
		for k,v in kwds.iteritems():
			setattr(ret, k, v)	
		
		ret.put()
		return ret
	
	@property
	def tag_lists(self):
		return db.GqlQuery('select * from TagList where tag_keys = :1', self.key())
	
	@classmethod
	def get_by_tag_name(cls, tag_name):
		""" returns the tag with this tag name """
		return db.Query(cls).filter('tag_name =', tag_name).get()
		
	def delete(self):
		for n in self.tag_lists:
			n.tag_keys.remove(self.key())
			n.put()
		db.delete(self.key())

#========================================================================================
# ironcap.data.tags.TagList
#========================================================================================
class TagList(db.Model):
	""" TagList is a class that can be applied to entities to make them taggable """
	reference    = db.ReferenceProperty	 (db.Model)
	tag_keys     = db.ListProperty       (db.Key)
	
	@classmethod
	def create(cls, **kwds):
		""" creates a new tag collection """
		ret = cls( key_name=str(uuid.uuid4()), **kwds)

		# apply keywords
		for k,v in kwds.iteritems():
			setattr(ret, k, v)	

		ret.put()
		return ret
	
	def add(self, tag_name):
		""" adds a tag to this entity """
		tag = Tag.get_by_tag_name(tag_name)
		if not tag:
			tag = Tag.create(tag_name=tag_name)
		self.tag_keys.append(tag.key())
		self.put()
		return tag
		
	def remove(self, tag_name):
		""" removes a tag to this entity """
		tag = tag.get_by_tag_name(tag_name)
		if tag:
			if tag.key() in self.tag_names:
				self.tag_names.remove(tag.key())
				self.put()
	
	@property
	def tags(self):
		""" returns all the tags for this entity """
		ret = []
		for n in db.get(self.tag_names):
			result.append(Tag.get_by_key_name(n))
		return ret
		
	def delete(self):
		db.delete(self.key())
	
		